from typing import Optional

from django.conf import settings
from django.utils.translation import gettext as _

from apps.app_tx_meeting.managers import tx_meeting_configs
from apps.app_users.email_sender import EmailSender, EmailConfig
from apps.app_users.models import Email


class TxMeetingEmailHandle:

    @staticmethod
    def get_email_configs() -> EmailConfig:
        """
        全局默认邮件配置

        :raises: Exception
        """
        configs = tx_meeting_configs.get_configs_no_cache(remove_invalid=False)
        use_ssl = configs[tx_meeting_configs.ConfigName.EMAIL_USE_SSL.value]
        use_tls = configs[tx_meeting_configs.ConfigName.EMAIL_USE_TLS.value]
        use_ssl = True if use_ssl == 'true' else False
        use_tls = True if use_tls == 'true' else False
        if use_tls and use_ssl:
            raise Exception(_('邮件配置信息有误，TLS和SSL加密只能有一个为"true"'))

        return EmailConfig(
            host=configs[tx_meeting_configs.ConfigName.EMAIL_HOST.value],
            port=int(configs[tx_meeting_configs.ConfigName.EMAIL_PORT.value]),
            host_user=configs[tx_meeting_configs.ConfigName.EMAIL_HOST_USER.value],
            host_password=configs[tx_meeting_configs.ConfigName.EMAIL_HOST_PASSWORD.value],
            use_tls=use_tls,
            use_ssl=use_ssl
        )

    @staticmethod
    def get_connection(fail_silently: bool = False, email_config: Optional[EmailConfig] = None):
        """
        全局默认邮件配置的连接
        """
        if email_config is None:
            email_config = TxMeetingEmailHandle.get_email_configs()

        return EmailSender.get_connection(
            host=email_config.host,
            port=email_config.port,
            username=email_config.host_user,
            password=email_config.host_password,
            use_tls=email_config.use_tls,
            use_ssl=email_config.use_ssl,
            timeout=settings.EMAIL_TIMEOUT,
            ssl_keyfile=settings.EMAIL_SSL_KEYFILE,
            ssl_certfile=settings.EMAIL_SSL_CERTFILE,
            fail_silently=fail_silently
        )

    @staticmethod
    def save_email(
            subject: str, receivers: list, message: str, tag: str, email_conf: EmailConfig,
            html_message: str = None, save_db: bool = True, remote_ip: str = '', is_feint: bool = False
    ):
        email = EmailSender.build_save_email(
            host=email_conf.host, sender=email_conf.host_user,
            subject=subject, receivers=receivers, message=message, tag=tag, html_message=html_message,
            save_db=save_db, remote_ip=remote_ip, is_feint=is_feint
        )

        return email

    @staticmethod
    def send_email(
            email: Email, receivers: list = None, fail_silently=True, save_db: bool = True,
            email_conf: Optional[EmailConfig] = None
    ) -> Optional[Exception]:
        connection = TxMeetingEmailHandle.get_connection(fail_silently=fail_silently, email_config=email_conf)

        exc = EmailSender.do_send_email(
            connection=connection, email=email, save_db=save_db, receivers=receivers)
        if exc is not None and not fail_silently:
            raise exc

        return exc
